home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 3d / ravecontextsample / source / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  14.9 KB  |  633 lines

  1. /****************************/
  2. /*       PROCESS.C             */
  3. /* By Brian Greenstone      */
  4. /****************************/
  5.  
  6.  
  7. /****************************/
  8. /*    EXTERNALS             */
  9. /****************************/
  10. #include <Resources.h>
  11. #include <Sound.h>
  12.  
  13. #include <Rave.h>
  14. #include <QD3D.h>
  15. #include <QD3DGeometry.h>
  16. #include <QD3DMath.h>
  17. #include <QD3DGroup.h>
  18. #include <QD3DTransform.h>
  19.  
  20. #include "myglobals.h"
  21. #include "misc.h"
  22. #include "process.h"
  23. #include "qd3d_support.h"
  24.  
  25. extern    float                gFramesPerSecond;
  26.  
  27.  
  28. /****************************/
  29. /*    PROTOTYPES            */
  30. /****************************/
  31.  
  32. static void InitModelWindow(void);
  33. static void BuildTestModel(void);
  34. static void SubmitMyStuff(QD3DSetupOutputType *viewInfo);
  35. static void GetMyRAVEInfo(void);
  36. static void MyRaveInvalidateCallback(TQ3RendererObject rendererRef);
  37. static void DoMyRAVECalls(void);
  38.  
  39.  
  40. /****************************/
  41. /*    CONSTANTS             */
  42. /****************************/
  43.  
  44. #define    MODEL_WIND_ID            400
  45.  
  46. #define    MY_HITHER                 10
  47. #define MY_YON                    500
  48.  
  49. #define    NUM_OBJECTS                12
  50.  
  51. #define    MAX_CONTEXTS            4                            // assume no sane person will have more than 4 monitors on their system
  52.  
  53. #define BACKGROUND_WIDTH        400
  54. #define    BACKGROUND_HEIGHT        400
  55.  
  56.  
  57. /*********************/
  58. /*    VARIABLES      */
  59. /*********************/
  60.  
  61.  
  62. WindowPtr                gModelWindow = nil;
  63. QD3DSetupOutputType        gModelViewInfo;
  64. TQ3Object                gModelGroup = nil;
  65. TQ3GroupObject            gBaseGroup[NUM_OBJECTS];
  66.  
  67. TQ3AttributeSet        gTextureAttr;
  68.  
  69. TQ3Matrix4x4    gRotMatrix[NUM_OBJECTS];
  70. TQ3Matrix4x4    gMoveMatrix[NUM_OBJECTS];
  71. TQ3Object        gTransformObject[NUM_OBJECTS];
  72. TQ3ColorARGB    gClearColor = {1,0,0,0};
  73.  
  74. unsigned long    gNumContexts = 0;
  75. TQADrawContext     *gContexts[MAX_CONTEXTS];                        // pointer to array of (TQADrawContext *)
  76.  
  77. unsigned long    gNumEngines = 0;
  78. TQAEngine         *gEngines[MAX_CONTEXTS];                        // pointer to array of (TQAEngine *)
  79.  
  80. TQABitmap        *gBitmap[MAX_CONTEXTS];
  81.  
  82. #pragma mark ========INITIALIZATION STUFF=========
  83.  
  84. /******************** INIT TEST ************************/
  85.  
  86. void InitTest(void)
  87. {
  88. int        i;
  89. TQ3Matrix4x4    m;
  90.  
  91.             /* INIT THE WINDOW */
  92.             
  93.     InitModelWindow();
  94.  
  95.  
  96.             /* CREATE THE TEST MODEL */
  97.             
  98.     BuildTestModel();
  99.  
  100.  
  101.             /* CREATE DISPLAY GROUPS */
  102.             
  103.     for (i = 0; i < NUM_OBJECTS; i++)
  104.     {
  105.         gBaseGroup[i] = Q3DisplayGroup_New();                                // make display group     
  106.     
  107.         Q3Matrix4x4_SetRotate_XYZ(&gRotMatrix[i], RandomFloat() * kQ3Pi,    // start @ random rotation
  108.                                                         RandomFloat() * kQ3Pi,
  109.                                                         RandomFloat() * kQ3Pi);
  110.  
  111.         Q3Matrix4x4_SetTranslate(&gMoveMatrix[i], RandomFloat() * 100 - 50,    // start @ random location
  112.                                                         RandomFloat() * 100 - 50,
  113.                                                         -20);
  114.     
  115.         Q3Matrix4x4_Multiply(&gRotMatrix[i], &gMoveMatrix[i], &m);            // accumulate matrices
  116.     
  117.         gTransformObject[i] = Q3MatrixTransform_New(&m);                    // make transform object
  118.         
  119.         Q3Group_AddObject(gBaseGroup[i], gTransformObject[i]);                // add transform to group        
  120.         Q3Group_AddObject(gBaseGroup[i], gModelGroup);                        // add geometry to group 
  121.     }
  122.  
  123.             /* DRAW THE WINDOW */
  124.                         
  125.     DrawModelWindow();
  126. }
  127.  
  128. /**************** CLEANUP TEST *********************/
  129. //
  130. // Called at quit
  131. // 
  132.  
  133. void CleanupTest(void)
  134. {
  135. int    i;
  136.  
  137.     for (i = 0; i < NUM_OBJECTS; i++)
  138.     {
  139.         if (gBaseGroup[i])
  140.             Q3Object_Dispose(gBaseGroup[i]);
  141.         if (gTransformObject[i])
  142.             Q3Object_Dispose(gTransformObject[i]);
  143.     }
  144.     
  145.     if (gModelGroup)
  146.         Q3Object_Dispose(gModelGroup);
  147.         
  148.         /* UNLOAD BITMAPS */
  149.         
  150.     for (i = 0; i < gNumEngines; i++)    
  151.     {
  152.         if (gBitmap[i])
  153.             QABitmapDelete(gEngines[i], gBitmap[i]);
  154.     }
  155. }
  156.  
  157.  
  158. /************** INIT MODEL WINDOW *******************/
  159. //
  160. // Create window & setup QuickDraw 3D View and Draw Context stuff.
  161. //
  162.  
  163. static void InitModelWindow(void)
  164. {
  165. QD3DSetupInputType    viewDef;
  166. TQ3Point3D            cameraFrom = { 0,0, 100 };
  167. TQ3Point3D            cameraTo = { 0, 0, 0 };
  168. TQ3Vector3D            cameraUp = { 0.0, 1.0, 0 };
  169. TQ3ColorRGB            ambientColor = { 1.0, 1.0, 1.0 };
  170. TQ3Vector3D            fillDirection1 = {1, -.3, -.8 };
  171. TQ3Vector3D            fillDirection2 = { -1, -.1, -.2 };
  172.  
  173.  
  174.             /* CREATE THE WINDOW */
  175.             
  176.     gModelWindow = GetNewCWindow(MODEL_WIND_ID, nil,MOVE_TO_FRONT);
  177.     if (gModelWindow == nil)
  178.         DoFatalAlert("\pWhere did the GameWindow window go?");                    
  179.     SetPort((GrafPtr)gModelWindow);
  180.     SizeWindow(gModelWindow, BACKGROUND_WIDTH, BACKGROUND_HEIGHT, true);
  181.  
  182.  
  183.             /* CREATE QD3D VIEW */
  184.  
  185.     viewDef.view.displayWindow         = gModelWindow;
  186.     viewDef.view.rendererType         = kQ3RendererTypeInteractive;
  187.     viewDef.view.clearColor         = gClearColor;
  188.     viewDef.view.paneClip.left         = 0;
  189.     viewDef.view.paneClip.right     = 0;
  190.     viewDef.view.paneClip.top         = 0;
  191.     viewDef.view.paneClip.bottom     = 0; 
  192.  
  193.     viewDef.styles.interpolation     = kQ3InterpolationStyleVertex; 
  194.     viewDef.styles.backfacing         = kQ3BackfacingStyleBoth;
  195.     viewDef.styles.fill                = kQ3FillStyleFilled; 
  196.     viewDef.styles.illuminationType    = kQ3IlluminationTypePhong; 
  197.  
  198.     viewDef.camera.from             = cameraFrom;
  199.     viewDef.camera.to                 = cameraTo;
  200.     viewDef.camera.up                 = cameraUp;
  201.     viewDef.camera.hither             = MY_HITHER;
  202.     viewDef.camera.yon                 = MY_YON;
  203.     viewDef.camera.fov                 = 1.0;
  204.  
  205.     viewDef.lights.ambientBrightness = 0.5;
  206.     viewDef.lights.ambientColor     = ambientColor;
  207.     viewDef.lights.numFillLights     = 2;
  208.     viewDef.lights.fillDirection[0] = fillDirection1;
  209.     viewDef.lights.fillDirection[1] = fillDirection2;
  210.     viewDef.lights.fillColor[0]     = ambientColor;
  211.     viewDef.lights.fillColor[1]     = ambientColor;
  212.     viewDef.lights.fillBrightness[0] = 1.1;
  213.     viewDef.lights.fillBrightness[1] = 0.4;
  214.  
  215.     QD3D_SetupWindow(&viewDef, &gModelViewInfo);    
  216.  
  217.  
  218.             /* GET RAVE DRAW CONTEXTS */
  219.     
  220.     GetMyRAVEInfo();
  221.     
  222.         
  223.             /* SET SOME RAVE INFO */
  224.             
  225.     DoMyRAVECalls();
  226. }
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233. /********************* BUILD TEST MODEL **************************/
  234.  
  235. static void BuildTestModel(void)
  236. {
  237. TQ3TriMeshData                    myTriMeshData;
  238. TQ3TriMeshAttributeData            vertexAttribs[3],faceAttribs;
  239.  
  240. TQ3Point3D points[3] = 
  241. {
  242.     0,35,0,
  243.     -35,-35,0,
  244.     35,-35,0
  245. };
  246.  
  247. TQ3Vector3D    vertexNormals[3] = 
  248. {
  249.     0,0,1,
  250.     0,0,1,
  251.     0,0,1
  252. };
  253.  
  254. TQ3Vector3D    faceNormals[1] =
  255. {
  256.     0,0,1
  257. };
  258.  
  259. TQ3Param2D uvArray[3] =
  260. {
  261.     .5,1,
  262.     0,0,
  263.     1,0
  264. };
  265.  
  266.  
  267. TQ3TriMeshTriangleData    triangles[1] =
  268. {
  269.     0,1,2
  270. };
  271.         
  272.  
  273. TQ3SurfaceShaderObject    texture;
  274.  
  275.  
  276.             /* FIRST LOAD THE TEXTUREMAP */
  277.                     
  278.     texture = QD3D_GetTextureMap(128,nil);
  279.         
  280.     gTextureAttr = Q3AttributeSet_New();
  281.     Q3AttributeSet_Add(gTextureAttr, kQ3AttributeTypeSurfaceShader, &texture);        
  282.     
  283.     
  284.             /* ASSIGN TRANSPARENCY ATTRIBUTE */
  285.                 
  286. //    transColor.r = transColor.g = transColor.b = 1.0;
  287. //    Q3AttributeSet_Add(gTextureAttr, kQ3AttributeTypeTransparencyColor, &transColor);
  288.  
  289.  
  290.             /* BUILD MAIN TRIMESH DATA STRUCTURE */
  291.  
  292.     myTriMeshData.triMeshAttributeSet = gTextureAttr;
  293.  
  294.     myTriMeshData.numTriangles = 1;
  295.     myTriMeshData.triangles = &triangles[0];
  296.  
  297.     myTriMeshData.numTriangleAttributeTypes = 1;
  298.     myTriMeshData.triangleAttributeTypes = &faceAttribs;
  299.  
  300.     myTriMeshData.numEdges = 0;
  301.     myTriMeshData.edges = nil;
  302.     myTriMeshData.numEdgeAttributeTypes = 0;
  303.     myTriMeshData.edgeAttributeTypes = nil;
  304.  
  305.     myTriMeshData.numPoints = 3;
  306.     myTriMeshData.points = &points[0];
  307.  
  308.     myTriMeshData.numVertexAttributeTypes = 1;
  309.      myTriMeshData.vertexAttributeTypes = &vertexAttribs[0];
  310.  
  311.  
  312.             /* CALCULATE BOUNDING BOX */
  313.  
  314.     Q3BoundingBox_SetFromPoints3D(&myTriMeshData.bBox, &points[0],    3, sizeof(TQ3Point3D));
  315.  
  316.  
  317.             /* CREATE FACE ATTRIBUTES */ 
  318.  
  319.     faceAttribs.attributeType = kQ3AttributeTypeNormal;
  320.     faceAttribs.data = &faceNormals[0];
  321.     faceAttribs.attributeUseArray = nil;
  322.  
  323.  
  324.             /* CREATE VERTEX ATTRIBUTES */ 
  325.  
  326.     vertexAttribs[0].attributeType = kQ3AttributeTypeSurfaceUV;
  327.     vertexAttribs[0].data = &uvArray[0];
  328.     vertexAttribs[0].attributeUseArray = nil;
  329.  
  330.  
  331.         /* MAKE THE TRIMESH GEOMETRY OBJECT */
  332.  
  333.     gModelGroup = Q3TriMesh_New(&myTriMeshData);
  334.     if (gModelGroup == nil)
  335.         DoFatalAlert("\pQ3TriMesh_New failed!");
  336.  
  337.  
  338. }
  339.  
  340.  
  341. #pragma mark =========UPDATING============
  342.  
  343.  
  344. /*************** DO MODEL WINDOW NULL EVENT **********************/
  345.  
  346. void DoModelWindowNullEvent(void)
  347. {
  348. TQ3Matrix4x4    m,m2;
  349. int                i;
  350.  
  351.             /* ROTATE THE GEOMETRY */
  352.             
  353.     QD3D_CalcFramesPerSecond();
  354.     Q3Matrix4x4_SetRotate_XYZ(&m,0.4/gFramesPerSecond,0.5/gFramesPerSecond,0);
  355.     
  356.     for (i = 0; i < NUM_OBJECTS; i++)
  357.     {
  358.         Q3Matrix4x4_Multiply(&m,&gRotMatrix[i],&gRotMatrix[i]);            // rotate it
  359.         Q3Matrix4x4_Multiply(&gRotMatrix[i], &gMoveMatrix[i], &m2);        // accumulate matrices
  360.             
  361.         Q3MatrixTransform_Set(gTransformObject[i],&m2);                    // update transform object
  362.     }
  363.  
  364.             /* REDRAW IT */
  365.                 
  366.     DrawModelWindow();
  367. }
  368.  
  369.  
  370. /******************* DRAW MODEL WINDOW *********************/
  371. //
  372. // Calls the support function QD3D_DrawScene.
  373. // It passes the view info and a pointer to the game draw callback.
  374. //
  375.  
  376. void DrawModelWindow(void)
  377. {
  378.             /* DRAW STUFF */
  379.             
  380.     QD3D_DrawScene(&gModelViewInfo,(void *)SubmitMyStuff);
  381. }
  382.  
  383.  
  384. /*************** SUBMIT MY STUFF ******************/
  385.  
  386. static void SubmitMyStuff(QD3DSetupOutputType *viewInfo)
  387. {
  388. int    i;
  389. static TQAVGouraud    vertex;
  390.  
  391.     vertex.x = 0;
  392.     vertex.y = 0;
  393.     vertex.z = .9999;
  394.     vertex.invW = 1.0;
  395.     vertex.r = .5;
  396.     vertex.g = .5;
  397.     vertex.b = .5;
  398.     vertex.a = 1.0;
  399.  
  400.     for (i = 0; i < gNumContexts; i++)                                            // draw bitmaps in background
  401.     {
  402.         if (gBitmap[i] != nil)
  403.             QADrawBitmap(gContexts[i], &vertex, gBitmap[i]);
  404.     }
  405.  
  406.     for (i = 0; i < NUM_OBJECTS; i++)
  407.     {
  408.         Q3Object_Submit(gBaseGroup[i],viewInfo->viewObject);                    // submit the geometry
  409.     }
  410. }
  411.  
  412.  
  413.  
  414. #pragma mark =========== RAVE CONTEXT STUFF ====================
  415.  
  416.  
  417.  
  418. /********************** GET MY RAVE INFO ***********************/
  419. //
  420. // Gets pointers to the RAVE Draw Contexts uses by our view and renderer.
  421. //
  422.  
  423. static void GetMyRAVEInfo(void)
  424. {
  425. TQ3ViewObject        theView;
  426. TQ3RendererObject    theRenderer;
  427. TQ3Status            status, viewStatus;
  428. TQAEngine             *engines[MAX_CONTEXTS];
  429. int                    i,j;
  430.  
  431.             /* GET RENDERER FROM VIEW */
  432.  
  433.     theView = gModelViewInfo.viewObject;
  434.     status = Q3View_GetRenderer(theView,&theRenderer);
  435.     if (status == kQ3Failure)
  436.         DoFatalAlert("\pGetMyRAVEInfo: Q3View_GetRenderer failed!");
  437.         
  438.     
  439.             /*************************/
  440.             /* GET THE RAVE CONTEXTS */
  441.             /*************************/
  442.             //
  443.             // 1.     Call _StartRendering to make sure RAVE contexts have been created.
  444.             // 2.    Call _GetRAVEDrawContexts to retrieve the RAVE contexts & setup a callback.
  445.             // 3.    Call _Cancel & _EndRendering to finish it.
  446.             //            
  447.  
  448.     viewStatus = Q3View_StartRendering(theView);                                // enter render loop
  449.     
  450.     status = Q3InteractiveRenderer_GetRAVEDrawContexts(theRenderer,                // pass in renderer
  451.                                                      gContexts,                    // fill this array with pointers to Draw Contexts
  452.                                                      engines,                    // fill this array with pointers to Draw Engines
  453.                                                      &gNumContexts,                // recieves # draw contexts gotten
  454.                                                      MyRaveInvalidateCallback);    // callback function to use when Contexts change
  455.     if (status == kQ3Failure)
  456.         DoFatalAlert("\pGetMyRAVEInfo: Q3InteractiveRenderer_GetRAVEDrawContexts failed!");
  457.     
  458.     if (viewStatus == kQ3Success)                                                // if we're in a render loop, we need to cancel it
  459.     {
  460.         status = Q3View_Cancel(theView);                                        // exit render loop
  461.         if (status == kQ3Failure)
  462.             DoFatalAlert("\pGetMyRAVEInfo: Q3View_Cancel failed!");
  463.         Q3View_EndRendering(theView);                                            // *must* call EndRendering after a Cancel
  464.     }
  465.  
  466.             /* VERIFY IF WE GOT ANYTHING */
  467.             //
  468.             // NOTE: if the user window shades a window, then we might
  469.             //        get zero here.  An app should handle this gracefully,
  470.             //        but we are not really doing so here.  Here we just bail out
  471.             //        but we never attempt to get the draw contexts again.
  472.             //
  473.             
  474.             
  475.     if (gNumContexts == 0)
  476.     {
  477.         DoAlert("\pNo RAVE Contexts exist");
  478.         return;
  479.     }
  480.         
  481.         
  482.         /* REMOVE DUPLICATES FROM ENGINES LIST */
  483.         //
  484.         // _GetRAVEDrawContexts returns a list of Draw Contexts and a parallel list of Drawing Engines for each Draw Context.
  485.         // The Engines list may contain multiple copies of the same engine since different Draw Contexts can use the
  486.         // same drawing engine (ie. multiple 3D windows on the same monitor).  Here, we scan thru the list and remove
  487.         // the duplicates since we only want one copy of each engine for this test app.
  488.         //
  489.  
  490.     gNumEngines = 0;
  491.     
  492.     for (i = 0; i < gNumContexts; i++)
  493.     {
  494.         for (j = 0; j < gNumEngines; j++)                // see if this engine is already in the global list
  495.         {        
  496.             if (engines[i] == gEngines[j])
  497.                 goto skip_me;
  498.         }
  499.         gEngines[gNumEngines++] = engines[i];            // this engine is unique, so put into global list        
  500. skip_me:;        
  501.     }    
  502.         
  503.         
  504.         
  505.                 /* CLEAN UP */
  506.                 
  507.     Q3Object_Dispose(theRenderer);                        
  508. }
  509.  
  510.  
  511. /******************* DO MY RAVE CALLS ************************/
  512. //
  513. // Uses the RAVE Draw Contexts to set up some fun stuff.
  514. //
  515.  
  516. static void DoMyRAVECalls(void)
  517. {
  518. int            i;
  519. TQAImage    image;
  520. TQAError    err;
  521. PicHandle    pict;
  522. GWorldPtr    gworld;
  523. Rect        r;
  524. GDHandle                oldGD;
  525. GWorldPtr                oldGW;
  526. PixMapHandle             hPixMap;
  527.  
  528.  
  529.     for (i = 0; i < gNumContexts; i++)                        // set the RAVE info on *all* of the contexts
  530.     {
  531.                 /* LET'S CHANGE THE BLENDING MODE */
  532.     
  533.         QASetInt(gContexts[i], kQATag_Blend, kQABlend_OpenGL);
  534.         QASetInt(gContexts[i], kQATagGL_BlendSrc, 1);
  535.         QASetInt(gContexts[i], kQATagGL_BlendDst, 1);
  536.     
  537.                 
  538.                 /* TURN OFF PERSPECTIVE Z */
  539.                 
  540.         QASetInt(gContexts[i], kQATag_PerspectiveZ, kQAPerspectiveZ_Off);
  541.     }
  542.     
  543.             /* LOAD A BITMAP TO USE FOR BACKGROUND */
  544.             //
  545.             // Must load it into all of the Engines being used.
  546.             //
  547.             
  548.                 /* DRAW PICT INTO GWORLD */
  549.                         
  550.     pict = GetPicture(129);                                        // load the PICT rez        
  551.     SetRect(&r, 0,0, BACKGROUND_WIDTH, BACKGROUND_HEIGHT);
  552.     NewGWorld(&gworld, 16, &r, 0, 0, 0L);                        // make gworld
  553.     GetGWorld(&oldGW, &oldGD);                                    // save current port
  554.     SetGWorld(gworld, nil);    
  555.     hPixMap = GetGWorldPixMap(gworld);                            // calc addr & rowbytes
  556.     LockPixels(hPixMap);                                        // lock gworld's pixels
  557.     DrawPicture(pict, &r);                                        // draw it
  558.     SetGWorld (oldGW, oldGD);
  559.     ReleaseResource((Handle)pict);                                // nuke the PICT rez
  560.             
  561.             /* SETUP RAVE IMAGE STURCTURE */
  562.             
  563.     image.width = r.right;
  564.     image.height = r.bottom;
  565.     image.rowBytes = (**hPixMap).rowBytes & 0x3fff;
  566.     image.pixmap = GetPixBaseAddr(hPixMap);
  567.             
  568.             
  569.             /* UPLOAD THE IMAGE TO ALL DRAWING ENGINES */
  570.                 
  571.     for (i = 0; i < gNumEngines; i++)    
  572.     {
  573.         err = QABitmapNew(gEngines[i], kQABitmap_NoCompression, kQAPixel_RGB16, &image, &gBitmap[i]);
  574.         if (err)
  575.             gBitmap[i] = nil;
  576.         else
  577.             QABitmapDetach (gEngines[i], gBitmap[i]);            // detach so I can nuke the gworld
  578.             
  579.     }
  580.  
  581.     DisposeGWorld(gworld);
  582.  
  583. }
  584.  
  585.  
  586. /****************** MY RAVE INVALIDATE CALLBACK ***********************/
  587. //
  588. //    INPUT:    rendererRef = reference to the renderer calling the callback.
  589. //                        You must not dispose of this reference in the callback!
  590. //
  591.  
  592. static void MyRaveInvalidateCallback(TQ3RendererObject rendererRef)
  593. {
  594. short    i;
  595.  
  596.     rendererRef;                                        // unused
  597.  
  598.     SysBeep(0);                                            // play beep when Draw Contexts get invalidated
  599.  
  600.     gNumContexts = 0;                                    // we aint got no contexts no more
  601.         
  602.             /* UNLOAD BITMAPS */
  603.             //
  604.             // since the context got nuked, I should probably unload the bitmaps I've loaded as well.
  605.             // These will be reloaded by function above.
  606.             //
  607.         
  608.     for (i = 0; i < gNumEngines; i++)    
  609.     {
  610.         if (gBitmap[i])
  611.         {
  612.             QABitmapDelete(gEngines[i], gBitmap[i]);
  613.             gBitmap[i] = nil;
  614.         }
  615.     }
  616.  
  617.  
  618.             /* GET NEW RAVE CONTEXTS & RESET THE RAVE TAGS */
  619.  
  620.     GetMyRAVEInfo();                                // get the contexts & engines
  621.     DoMyRAVECalls();                                // make my RAVE calls again to keep things setup the way I like
  622. }
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.